/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "keyboard_srv_proxy.h"
#include "ipc_types.h"
#include "message_option.h"
#include "message_parcel.h"
#include "hilog_wrapper.h"
#include "keyboard_errors.h"
#include "keyboard_common.h"
#include "ikeyboard_observer.h"
#include <string.h>

namespace SwanLink {
namespace  Finance{
using namespace OHOS;
bool KeyboardSrvProxy::IsSM4Enabled(int handle) {
    bool result = false;
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    if (!data.WriteInterfaceToken(KeyboardSrvProxy::GetDescriptor())) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "Write descriptor failed");
        return result;
    }
    WRITE_PARCEL_WITH_RET(data, Int32, handle, false);
    KEYBOARD_HILOGE(KEYBOARD_SRV, "handle: %{public}d", handle);
    int ret = remote->SendRequest(static_cast<int>(IKeyboardSrv::KEYBOARD_ISSM4ENABLED), data, reply, option);

    if (ret != ERR_OK) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "SendRequest is failed, ret: %d", ret);
        return result;
    }
    
    READ_PARCEL_WITH_RET(reply, Bool, result, false);
    KEYBOARD_HILOGE(KEYBOARD_SRV, "handle: %{public}d, Bool: %{public}d", handle, result);
    return result;
}

int KeyboardSrvProxy::GetSN(int handle, char sn[], int &len)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return -1;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    if (!data.WriteInterfaceToken(KeyboardSrvProxy::GetDescriptor())) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "Write descriptor failed");
        return -1;
    }
    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);
    int ret = remote->SendRequest(static_cast<int>(IKeyboardSrv::KEYBOARD_GETSN), data, reply, option);

    if (ret != ERR_OK) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "SendRequest is failed, ret: %d", ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, len, -1);
    READ_BUFFER_WITH_COPY(reply, char, sn, 1024, -1);
    READ_PARCEL_WITH_RET(reply, Int32, result, -1);

    return result;
}

int KeyboardSrvProxy::CalculateMAC(int handle, const KeyInfo& key, char plain[], int len, char enc_data[], int &enc_len)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    if (!data.WriteInterfaceToken(KeyboardSrvProxy::GetDescriptor())) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "Write descriptor failed");
        return result;
    }
    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);
    WRITE_BUFFER_WITH_RET(data, KeyInfo, &key, sizeof(KeyInfo), E_WRITE_PARCEL_ERROR);
    WRITE_PARCEL_WITH_RET(data, Int32, len, -1);
    if (len > 0)
        WRITE_BUFFER_WITH_RET(data, String, plain, len, -1);
    int ret = remote->SendRequest(static_cast<int>(IKeyboardSrv::KEYBOARD_CALCULATEMAC), data, reply, option);

    if (ret != ERR_OK) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "SendRequest is failed, ret: %d", ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, enc_len, result);
    READ_BUFFER_WITH_COPY(reply, char, enc_data, 2048, result);
    READ_PARCEL_WITH_RET(reply, Int32, result, result);

    return result;
}

int KeyboardSrvProxy::EncryptData(int handle, const KeyInfo& key, char plain[], int len, char enc_data[], int &len_enc)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) {
        return result;
    }
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    if (!data.WriteInterfaceToken(KeyboardSrvProxy::GetDescriptor())) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "Write descriptor failed");
        return result;
    }
    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);
    WRITE_BUFFER_WITH_RET(data, KeyInfo, &key, sizeof(KeyInfo), E_WRITE_PARCEL_ERROR);
    WRITE_PARCEL_WITH_RET(data, Int32, len, -1);
    if (len > 0)
        WRITE_BUFFER_WITH_RET(data, String, plain, len, -1);
    int ret = remote->SendRequest(static_cast<int>(IKeyboardSrv::KEYBOARD_ENCRYPTDATA), data, reply, option);

    if (ret != ERR_OK) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "SendRequest is failed, ret: %d", ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, len_enc, result);
    READ_BUFFER_WITH_COPY(reply, char, enc_data, 520, result);
    KEYBOARD_HILOGE(KEYBOARD_SRV, "9enc_data: %{public}s, len_enc : %{public}d",
                    enc_data, len_enc);
    READ_PARCEL_WITH_RET(reply, Int32, result, result);

    return result;
}

int KeyboardSrvProxy::SetPINLength(int handle, int minLen, int maxLen)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    if (!data.WriteInterfaceToken(KeyboardSrvProxy::GetDescriptor())) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "Write descriptor failed");
        return result;
    }
    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, minLen, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, maxLen, -1);
    int ret = remote->SendRequest(static_cast<int>(IKeyboardSrv::KEYBOARD_SETPINLENGTH), data, reply, option);

    if (ret != ERR_OK) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "SendRequest is failed, ret: %d", ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, ret, -1);
    return ret;
}

int KeyboardSrvProxy::SetTextMode(int handle, TextMode mode)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    if (!data.WriteInterfaceToken(KeyboardSrvProxy::GetDescriptor())) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "Write descriptor failed");
        return result;
    }
    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, mode, -1);

    int ret = remote->SendRequest(static_cast<int>(IKeyboardSrv::KEYBOARD_SETTEXTMODE), data, reply, option);

    if (ret != ERR_OK) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "SendRequest is failed, ret: %d", ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, ret, -1);
    return ret;
}

void KeyboardSrvProxy::ClearTextMode(int handle)
{
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    if (!data.WriteInterfaceToken(KeyboardSrvProxy::GetDescriptor())) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "Write descriptor failed");
        return;
    }
    WRITE_PARCEL_NO_RET(data, Int32, handle);
    int ret = remote->SendRequest(static_cast<int>(IKeyboardSrv::KEYBOARD_CLEARTEXTMODE), data, reply, option);

    if (ret != ERR_OK) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "SendRequest is failed, ret: %d", ret);
        return;
    }

    return;
}

int KeyboardSrvProxy::LoadMasterKey(int handle, KeyID masterKeyID, unsigned char *KeyValue)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    if (!data.WriteInterfaceToken(KeyboardSrvProxy::GetDescriptor())) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "Write descriptor failed");
        return result;
    }
    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, masterKeyID, -1);
    WRITE_PARCEL_WITH_RET(data, String, (char*)KeyValue, -1);
    int ret = remote->SendRequest(static_cast<int>(IKeyboardSrv::KEYBOARD_LOADMASTERKEY), data, reply, option);

    if (ret != ERR_OK) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "SendRequest is failed, ret: %d", ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, result, -1);

    return result;
}

int KeyboardSrvProxy::LoadUserKey(int handle, KeyID masterKeyID, userKeyType user_Key_Type, unsigned char *KeyValue)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    if (!data.WriteInterfaceToken(KeyboardSrvProxy::GetDescriptor())) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "Write descriptor failed");
        return result;
    }
    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, masterKeyID, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, user_Key_Type, -1);
    WRITE_PARCEL_WITH_RET(data, String, (char*)KeyValue, -1);
    int ret = remote->SendRequest(static_cast<int>(IKeyboardSrv::KEYBOARD_LOADUSERKEY), data, reply, option);

    if (ret != ERR_OK) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "SendRequest is failed, ret: %d", ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, result, result);

    return result;
}

int KeyboardSrvProxy::UpdateMasterKey(int handle, KeyID masterKeyID, unsigned char *KeyValue)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    if (!data.WriteInterfaceToken(KeyboardSrvProxy::GetDescriptor())) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "Write descriptor failed");
        return result;
    }
    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, masterKeyID, -1);
    WRITE_PARCEL_WITH_RET(data, String, (char*)KeyValue, -1);
    int ret = remote->SendRequest(static_cast<int>(IKeyboardSrv::KEYBOARD_UPDATEMASTERKEY), data, reply, option);

    if (ret != ERR_OK) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "SendRequest is failed, ret: %d", ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, result, -1);

    return result;
}

int KeyboardSrvProxy::UpdateUserKey(int handle, KeyID masterKeyID, userKeyType user_Key_Type, unsigned char *KeyValue) {
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    if (!data.WriteInterfaceToken(KeyboardSrvProxy::GetDescriptor())) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "Write descriptor failed");
        return result;
    }
    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, masterKeyID, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, user_Key_Type, -1);
    WRITE_PARCEL_WITH_RET(data, String, (char*)KeyValue, E_WRITE_PARCEL_ERROR);
    int ret = remote->SendRequest(static_cast<int>(IKeyboardSrv::KEYBOARD_UPDATEUSERKEY), data, reply, option);

    if (ret != ERR_OK) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "SendRequest is failed, ret: %d", ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, result, -1);

    return result;
}

int KeyboardSrvProxy::DeleteUserKey(int handle, KeyID masterKeyID, userKeyType user_Key_Type)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    if (!data.WriteInterfaceToken(KeyboardSrvProxy::GetDescriptor())) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "Write descriptor failed");
        return result;
    }
    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, masterKeyID, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, user_Key_Type, -1);
    int ret = remote->SendRequest(static_cast<int>(IKeyboardSrv::KEYBOARD_DELETEUSERKEY), data, reply, option);

    if (ret != ERR_OK) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "SendRequest is failed, ret: %d", ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, result, -1);

    return result;
}

void KeyboardSrvProxy::ListenForPin(int handle, PinListener* listener, int timeout) {
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;

    option.SetFlags(MessageOption::TF_ASYNC);
    if (!data.WriteInterfaceToken(KeyboardSrvProxy::GetDescriptor())) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "Write descriptor failed");
        return;
    }
    WRITE_PARCEL_NO_RET(data, Int32, handle);
    WRITE_PARCEL_NO_RET(data, Int32, timeout);
    if (listener != nullptr) {
        if (!data.WriteRemoteObject(static_cast<IKeyboardObserver*>(listener)->AsObject())) {
            KEYBOARD_HILOGE(KEYBOARD_SRV, "WriteRemoteObject is failed");
        }
    }

    int ret = remote->SendRequest(static_cast<int>(IKeyboardSrv::KEYBOARD_LISTENFORPIN), data, reply, option);

    if (ret != ERR_OK) {
        KEYBOARD_HILOGE(KEYBOARD_SRV, "SendRequest is failed, ret: %d", ret);
        return;
    }
    return;
}


} // namespace Finance
} // namespace SwanLink
